"""
@Author  : 康帅
@Time    : 2021/6/17 14:54
@Function: itertools产生新的值
"""

from itertools import *
import fractions


def itertools_count():
    """
    count() 函数返回一个产生一列连续整数的迭代器。
    我们可以传递一个参数来设定起始值。
    与内置函数 range() 不同，不需要给出一个参数来设定上限
    :return:
    """
    for i in zip(count(1), ['a', 'b', 'c']):
        print(i)


def itertools_count_step():
    """
    count() 函数的起始和步长参数可以是任意可相加的数
    :return:
    """
    start = fractions.Fraction(1, 3)
    step = fractions.Fraction(1, 3)

    for i in zip(count(start, step), ['a', 'b', 'c']):
        print('{}: {}'.format(*i))


def itertools_cycle():
    """
    cycle() 函数将会把输入的可迭代对象无限循环输出的迭代器。
    因此，这个函数会记住整个输入的迭代器，
    因此，这在输入迭代对象较长时会占用较多的内存
    :return:
    """
    for i in zip(range(7), cycle(['a', 'b', 'c'])):
        print(i)


def itertools_repeat():
    """
    repeat() 函数返回的迭代器会把一个值重复几次输出
    :return:
    """
    for i in repeat('over-and-over', 5):
        print(i)


def itertools_repeat_zip():
    """
    将 repeat() 和 zip() 以及 map() 组合起来使用是一种常用的，
    把一个值和其他迭代器组合在一起的方法
    :return:
    """
    for i, s in zip(count(1), repeat('over-and-over', 5)):
        print(i, s)


def itertools_repeat_map():
    """
    这里的 repeat() 迭代器不需要给出迭代的次数。
    因为 map() 函数会自动在其中任意一个输入终止时终止。
    而这里的 range() 只返回五个值
    :return:
    """
    for i in map(lambda x, y: (x, y, x * y), repeat(2), range(5)):
        print('{:d} * {:d} = {:d}'.format(*i))


if __name__ == '__main__':
    itertools_count()
    itertools_count_step()
    itertools_cycle()
    itertools_repeat()
    itertools_repeat_zip()
    itertools_repeat_map()
